package 热题100.链表.LRU缓存_146_中等;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

/*
请你设计并实现一个满足  LRU (最近最少使用) 缓存 约束的数据结构。
实现 LRUCache 类：
LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存
int get(int key) 如果关键字 key 存在于缓存中，则返回关键字的值，否则返回 -1 。
void put(int key, int value) 如果关键字 key 已经存在，则变更其数据值 value ；如果不存在，则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ，则应该 逐出 最久未使用的关键字。
函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。

示例：
输入
["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
输出
[null, null, null, 1, null, -1, null, -1, 3, 4]

解释
LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // 缓存是 {1=1}
lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}
lRUCache.get(1);    // 返回 1
lRUCache.put(3, 3); // 该操作会使得关键字 2 作废，缓存是 {1=1, 3=3}
lRUCache.get(2);    // 返回 -1 (未找到)
lRUCache.put(4, 4); // 该操作会使得关键字 1 作废，缓存是 {4=4, 3=3}
lRUCache.get(1);    // 返回 -1 (未找到)
lRUCache.get(3);    // 返回 3
lRUCache.get(4);    // 返回 4
* */
public class Solution {

}

class LRUCache {

    public int capacity;
    public LinkedList<Integer> keyList;
    public Map<Integer, Integer> cache;

    public LRUCache(int capacity) {
        this.capacity = capacity;
        keyList = new LinkedList<>();
        cache = new HashMap<>();
    }

    public int get(int key) {
        // 先看是否有数据，有就更新
        if (cache.containsKey(key)){
            keyList.remove(Integer.valueOf(key));
            keyList.addLast(key);
            return cache.get(key);
        }
        return 0;
    }

    public void put(int key, int value) {
        // 如果本身有该数据就从cache移除，并准备更新数据因为value会被更新
        if (cache.containsKey(key)){
            cache.remove(key);
        }
        // 如果没有该数据，且此时容量满了，那么就需要把最近不使用数据去掉
        while (cache.size() >= capacity){
            int oldKey = keyList.removeFirst();
            cache.remove(oldKey);
        }
        cache.put(key, value);
        keyList.addLast(key);
    }
}